/**
 * author      : dormi330
 * date        : 2018/6/24
 * project     : mybatis
 * description : 订单, 按照店铺进行隔离, 拥有一个或多个SKU
 * <p>
 * 一个订单包含多条 item, 但是一次支付
 * 物流可以包含多个
 */

package com.deep.trade.domain.order;

import com.deep.trade.common.BaseEntity;
import com.deep.trade.common.TradeException;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TradeOrder extends BaseEntity {

    // 订单状态机
    public static final String STATUS_TO_BE_AUDITED = "to_be_audited";  // 待审核 = toBeAudited
    public static final String STATUS_TO_BE_PAID = "to_be_paid";        // 待支付 = toBePaid
    public static final String STATUS_PAID = "paid";                    // 已支付 = paid
    public static final String STATUS_DELIVERYING = "deliverying";      // 已发货 = deliverying
    public static final String STATUS_FINISHED = "finished";            // 已完成 = finished
    public static final String STATUS_COMMENTED = "commented";          // 已评价 = commented
    public static final String STATUS_REFUNDING = "refunding";          // 退款中 = refunding
    public static final String STATUS_REFUNDED = "refunded";            // 已退款 = refunded
    public static final String STATUS_CANNELLED = "cancelled";          // 已取消 = cancelled
    public static final String STATUS_PAY_TIMEOUT = "pay_timeout";      // 支付超时 = payTimeout
    public static final String STATUS_AUDIT_REJECTED = "audit_rejected";// 已审核拒绝 = auditRejected
    public static final String STATUS_DELETED = "deleted";              // 已删除 = deleted

    // 常量 - 订单类型
    public static final String ORDER_TYPE_GENERAL = "general";

    private String orderSummaryId;              // 交易父订单(OrderSummary)id
    private String orderType;                   // 订单类型 目前只支持普通订单 general
    private String channelCode = "pc_web";      // 订单渠道
    private String channelName = "pc_web";      // 订单渠道
    private String code;                        // 订单编码

    private String sellerId;                    // 卖家Id
    private String sellerName;                  // 卖家名称
    private String shopId;                      // 店铺Id
    private String memberId;                    // 会员Id
    private String memberName;                  // 会员名称
    private String remark;                      // 备注
    private String sellerRemark;                // 卖家备注
    private String status;                      // 订单状态, 枚举

    // 与金额相关的信息
    private BigDecimal discountMoney;           // 店铺级优惠
    private BigDecimal freightMoney;            // 订单运费金额小计, 计算值
    private BigDecimal itemMoney;               // 商品金额小计, 计算值
    private BigDecimal payMoney;                // 实付金额, 计算值

    private String auditRejectReason;           // 审核拒绝原因
    private Date auditedAt;                     // 审核时间
    private int plock;                          // 锁, 1=被锁, 0=无锁, 在支付时用到

    public TradeOrder() {
        super();
    }

    // 非存储字段
    private List<TradeOrderSku> skuList = new ArrayList<>();

    public void addTradeOrderSku(TradeOrderSku sku) {
        sku.setTradeOrderId(this.getId());
        this.skuList.add(sku);
    }

    /**
     * 计算金额, 根据已有信息, 计算推导值
     */
    public void calculateMoney() {
        freightMoney = BigDecimal.ZERO;
        itemMoney = BigDecimal.ZERO;
        payMoney = BigDecimal.ZERO;

        for (TradeOrderSku tradeOrderSku : this.skuList) {
            freightMoney = freightMoney.add(tradeOrderSku.getFreightMoney());
            itemMoney = itemMoney.add(tradeOrderSku.getItemMoney());
            payMoney = payMoney.add(tradeOrderSku.getPayMoney());
        }
        payMoney = payMoney.subtract(discountMoney);

        // 如果小于0, 则置为0
        payMoney = payMoney.compareTo(BigDecimal.ZERO) == -1 ? BigDecimal.ZERO : payMoney;
    }

    /**
     * 进行审批
     *
     * @param isApprove    是否通过
     * @param rejectReason 拒绝原因
     * @throws TradeException
     */
    public void aduit(boolean isApprove, String rejectReason) throws TradeException {

        // 判断目前状态是否 可被审核
        if (!TradeOrder.STATUS_TO_BE_AUDITED.equals(status)) {
            throw new TradeException("order cannot be audit, current status=" + status);
        }

        // 审批通过 -> 待付款
        // 拒绝 -> reject
        auditedAt = new Date();
        if (isApprove) {
            status = TradeOrder.STATUS_TO_BE_PAID;
        } else {
            status = TradeOrder.STATUS_AUDIT_REJECTED;
            auditRejectReason = rejectReason;
        }
    }




    // setter and getter

    public String getOrderSummaryId() {
        return orderSummaryId;
    }

    public void setOrderSummaryId(String orderSummaryId) {
        this.orderSummaryId = orderSummaryId;
    }

    public String getOrderType() {
        return orderType;
    }

    public void setOrderType(String orderType) {
        this.orderType = orderType;
    }

    public String getChannelCode() {
        return channelCode;
    }

    public void setChannelCode(String channelCode) {
        this.channelCode = channelCode;
    }

    public String getChannelName() {
        return channelName;
    }

    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getSellerId() {
        return sellerId;
    }

    public void setSellerId(String sellerId) {
        this.sellerId = sellerId;
    }

    public String getSellerName() {
        return sellerName;
    }

    public void setSellerName(String sellerName) {
        this.sellerName = sellerName;
    }

    public String getShopId() {
        return shopId;
    }

    public void setShopId(String shopId) {
        this.shopId = shopId;
    }

    public String getMemberId() {
        return memberId;
    }

    public void setMemberId(String memberId) {
        this.memberId = memberId;
    }

    public String getMemberName() {
        return memberName;
    }

    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getSellerRemark() {
        return sellerRemark;
    }

    public void setSellerRemark(String sellerRemark) {
        this.sellerRemark = sellerRemark;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public BigDecimal getDiscountMoney() {
        return discountMoney;
    }

    public void setDiscountMoney(BigDecimal discountMoney) {
        this.discountMoney = discountMoney;
    }

    public BigDecimal getFreightMoney() {
        return freightMoney;
    }

    public void setFreightMoney(BigDecimal freightMoney) {
        this.freightMoney = freightMoney;
    }

    public BigDecimal getItemMoney() {
        return itemMoney;
    }

    public void setItemMoney(BigDecimal itemMoney) {
        this.itemMoney = itemMoney;
    }

    public BigDecimal getPayMoney() {
        return payMoney;
    }

    public void setPayMoney(BigDecimal payMoney) {
        this.payMoney = payMoney;
    }

    public String getAuditRejectReason() {
        return auditRejectReason;
    }

    public void setAuditRejectReason(String auditRejectReason) {
        this.auditRejectReason = auditRejectReason;
    }

    public Date getAuditedAt() {
        return auditedAt;
    }

    public void setAuditedAt(Date auditedAt) {
        this.auditedAt = auditedAt;
    }

    public int getPlock() {
        return plock;
    }

    public void setPlock(int plock) {
        this.plock = plock;
    }

    public List<TradeOrderSku> getSkuList() {
        return skuList;
    }

    public void setSkuList(List<TradeOrderSku> skuList) {
        this.skuList = skuList;
    }
}
